package com.toobigtofail.drum
{
	import flash.utils.Dictionary;
	
	import net.flashpunk.utils.Key;
	
	public class Notes
	{
		private static var _keyMappings:Dictionary = new Dictionary;
		private static var _stringMappings:Dictionary = null;
		private static var _keys:Array;
		
		public static const A:int = 1;
		public static const B:int = 2;
		public static const C:int = 3;
		public static const D:int = 4;
		
		public static const INVALID:int = int.MIN_VALUE;
		
		public static function mapNote(key:int, note:int):void {
			_keyMappings[key] = note;
			resetKeys();
		}
		
		public static function getNote(key:int):int {
			return _keyMappings[key];
		}
		
		public static function getKey(note:int):int {
			for (var key:* in _keyMappings) {
				if (_keyMappings[key] == note) {
					return key;
				}
			}
			return int.MIN_VALUE;
		}
		
		public static function get keys():Array {
			return _keys;
		}
		
		private static function resetKeys():void {
			_keys = new Array;
			for (var k:* in _keyMappings) {
				_keys.push(k);
			}
		}
		
		private static function initStringMappings():void {
			if (null == _stringMappings) {
				_stringMappings = new Dictionary;
				
				_stringMappings["A"] = A;
				_stringMappings["B"] = B;
				_stringMappings["C"] = C;
				_stringMappings["D"] = D;
			}
		}
		
		public static function fromString(str:String):int {
			initStringMappings();
			var note:int = _stringMappings[str];
			if (note) {
				return note;
			}
			
			throw new Error("Undefined note string " + str);
		}
		
		public static function toString(note:int):String {
			initStringMappings();
			for (var str:String in _stringMappings) {
				if (_stringMappings[str] == note) {
					return str;
				}
			}
			return null;
		}
	}
}